import 'dart:convert';

import 'package:architecture/log.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:study_demo/base/BaseController.dart';
import 'package:study_demo/ext/tile_ext.dart';
import 'package:study_demo/util/utils.dart';
import 'package:tile/tile.dart';

import '../api/api.dart';
import '../api/bean.dart';
import '../api/net.dart';

mixin OtherPlatformChessListener on BaseController, WidgetsBindingObserver {
  ///解析到其他平台的棋谱
  onResponseFromOtherPlatform(String sgf);

  @override
  void onInit() {
    WidgetsBinding.instance.addObserver(this);
    super.onInit();
    _parse();
  }

  cancelObserver() {
    WidgetsBinding.instance.removeObserver(this);
  }

  addObserver() {
    WidgetsBinding.instance.removeObserver(this);
  }

  @override
  void onClose() {
    WidgetsBinding.instance.removeObserver(this);
    super.onClose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state != AppLifecycleState.resumed) return;
    _parse();
  }

  _parse() async {
    ClipboardData? boardData;

    try {
      boardData = await Clipboard.getData(Clipboard.kTextPlain);
    } catch (e) {
      Log.e(e);
      return;
    }

    var clipText = boardData != null ? boardData.text! : '';

    if (clipText.isEmpty || !isValidUrl(clipText)) {
      return;
    }
    Clipboard.setData(const ClipboardData(text: ''));
    Log.i('clipText===>$clipText');

    if (_isYK(clipText)) {
      //https://home.yikeweiqi.com/mobile.html#/sgf/detail?id=341758&type=2
      //https://api.yikeweiqi.com/usersgf/detail?type=2&id=341758
      //https://home.yikeweiqi.com/mobile.html#/golive/room/122802/1/159245154
      _parseYK(clipText);
    } else if (_isYC(clipText)) {
      //http://mobile.eweiqi.com/index_ZHCN.html?LNK=2&SIP=966deb80&RNO=1580&RES=ch&WID=XieKer&BID=OSYoo
      //http://mobile.eweiqi.com/index_ZHCN.html?LNK=1&GNO=1186234356&USR=1&RES=ch
      //http://mobile.eweiqi.com/index_ZHCN.html?LNK=1&GNO=162751&USR=0&RES=ch
      //http://client.eweiqi.com/gibo/gibo_load_data.php?id=1186234356&mode=my
      //http://mobile.eweiqi.com/index_ZHCN.html?LNK=3&GFILE=http://share.eweiqi.com/20220525/1653467410.sgf&RES=ch
      _parseYC(clipText);
    } else if (_isYH(clipText)) {
      //http://h5.foxwq.com/txwqshare/index.html?chessid=1673175594030041843&boardsize=19&title=%E9%87%8E%E7%8B%90%E5%9B%B4%E6%A3%8B%20-%20%E7%BD%91%E6%A3%8B%E6%A3%8B%E8%B0%B1&sourcetype=pc
      //http://h5.foxwq.com/qqgameweiqi/chessbook_local/YHWQFetchChess?chessid=1673175594030041843
      _parseYH(clipText);
    } else if (_isTX(clipText)) {
      //http://h5.foxwq.com/txwqshare/index.html?chessid=1639640717030002783&title=%E3%80%90%E7%BD%91%E6%A3%8B%E6%A3%8B%E8%B0%B1%E3%80%91&desc=%E4%BD%99%E9%94%902018%5B7%E6%AE%B5%5D%20VS%20%E9%A3%8E36579273%5B17%E7%BA%A7%5D&catelog=2&statisticsShareType=4&clientType=64
      //https://cgi.huanle.qq.com/happyapp/cgi-bin/CommonMobileCGI/TXWQFetchChess?chessid=1639640717030002783
      _parseTX(clipText);
    } else if (_isTXSE(clipText)) {
      //https://share.foxwq.com/edushare/index.html?svrid=0&svrtype=0&roomid=0&createtime=0&chessid=1640661278030032173&boardsize=9&chessrule=1
      //http://134.175.232.138:33631/chessbook/FetchChessBookByID?id=1640661278030032173
      _parseTXSE(clipText);
    } else if (_isJJ(clipText)) {
      //http://wxsgf.99weiqi.com/web/?sgfid=191990081&size=13
      //http://getsgf.99weiqi.com/wxsgf.aspx?index=191990081
      _parseJJ(clipText);
    } else if (_isJY(clipText)) {
      //http://chess.91goodgo.com/index.php?s=/User/share/&id=8312871&uid=163645
      //http://chess.91goodgo.com/index.php?s=/User/share/&id=8312871&uid=163645
      _parseJY(clipText);
    } else if (_isXB(clipText)) {
      //http://duiyi.xbkids.cn/wx/pu/lookChess.htm?pid=307705908&from=singlemessage
      //https://duiyi.xbkids.cn/wx/pu/getpudata.php?pid=307705908
      _parseXB(clipText);
    } else if (_isYKSE(clipText)) {
      // clipText =
      //     'https://shaoer.yikeweiqi.com/game_analysis_mobile.html?p=ZXlKMWMyVnlVMmRtUkdWd2IzUkpaQ0k2TmpRMk16RXpOako5';
      _parseYKSE(clipText);
    } else if (_isYZ(clipText)) {
      _parseYZ(clipText);
    } else if (_isXZ(clipText)) {
      //https://m.19x19.com/app/dark/zh/sgf/34756224
      //https://m.19x19.com/app/dark/zh/report/55767586
      //https://m.19x19.com/app/dark/zh/live/159049
      //https://www.19x19.com/engine/live/data/159540
      _parseXZ(clipText);
    }
  }

  bool _isYH(String text) {
    return text.contains(r"//h5.foxwq.com/");
  }

  bool _isTX(String text) {
    return text.contains(r"//h5.txwq.qq.com/");
  }

  bool _isTXSE(String text) {
    return text.contains(r"//share.foxwq.com/");
  }

  bool _isYC(String text) {
    return text.contains(r"//mobile.eweiqi.com/");
  }

  bool _isYK(String text) {
    return text.contains(r"//home.yikeweiqi.com/");
  }

  bool _isJJ(String text) {
    return text.contains(r"//wxsgf.99weiqi.com/");
  }

  bool _isJY(String text) {
    return text.contains(r"//chess.91goodgo.com/");
  }

  bool _isXB(String text) {
    return text.contains(r"//weiqi.xinboduiyi.com/");
  }

  bool _isYKSE(String text) {
    return text.contains(r"//shaoer.yikeweiqi.com/");
  }

  bool _isYZ(String text) {
    return text.contains(r"//app.izis.cn");
  }

  bool _isXZ(String text) {
    return text.contains(r"//m.19x19.com") || text.contains(r"//www.19x19.com");
  }

  _parseYK(String clipText) async {
    int id = 0;
    var matchId = RegExp(r".*id=(\d+).*").firstMatch(clipText);
    if (matchId != null) {
      id = int.parse(matchId.group(1)!);
    }
    int type = 0;
    var matchType = RegExp(r".*type=(\d+).*").firstMatch(clipText);
    if (matchType != null) {
      type = int.parse(matchType.group(1)!);
    }

    var response = await Dio(BaseOptions(
            connectTimeout: const Duration(milliseconds: 15 * 1000)))
        .get("https://api.yikeweiqi.com/usersgf/detail?${'type=$type&'}id=$id");
    onResponseFromOtherPlatform(response.data['Result']['Sgf']);
  }

  bool isError = false;

  _parseYC(String clipText) async {
    // 弈城9路用的sgf，19路用的gib
    String sgfFile;
    var matchSgf = RegExp(r".*GFILE=(http.*\.sgf).*").firstMatch(clipText);
    if (matchSgf != null) {
      sgfFile = matchSgf.group(1)!;
      var response = await Dio(BaseOptions(
              connectTimeout: const Duration(milliseconds: 15 * 1000)))
          .get(sgfFile);
      onResponseFromOtherPlatform(response.data);
      return;
    }

    int id = 0;
    var matchId = RegExp(r".*GNO=(\d+).*").firstMatch(clipText);
    if (matchId != null) {
      id = int.parse(matchId.group(1)!);
    }
    int mode = 0;
    var matchMode = RegExp(r".*USR=(\d+).*").firstMatch(clipText);
    if (matchMode != null) {
      mode = int.parse(matchMode.group(1)!);
    }
    var response;
    try {
      isError = false;
      response = await Dio(BaseOptions(
              connectTimeout: const Duration(milliseconds: 15 * 1000)))
          .get(
              "http://client.eweiqi.com/gibo/gibo_load_data.php?id=$id${mode == 1 ? '&mode=my' : ''}");
    } catch (e) {
      isError = true;
      response = await Dio(BaseOptions(
              connectTimeout: const Duration(milliseconds: 15 * 1000),
              responseType: ResponseType.plain))
          .get(
              "http://client.eweiqi.com/gibo/gibo_load_data.php?id=$id${mode == 1 ? '&mode=my' : ''}");
    }

    String result = response.data;
    String blackName = "";
    String whiteName = "";
    Board board = Board(19);
    var data = result.split('\n');
    data.forEach((line) {
      //\[GAMEWHITENAME=石油工人好(9段)\]
      // \[GAMEBLACKNAME=傲雪玉龙(3段)\]
      if (line.contains(!isError ? "GAMEBLACKNAME" : "BUSERINFO=BID")) {
        var regex = !isError
            ? RegExp(r".*GAMEBLACKNAME=([^\\]*).*")
            : RegExp(r".*BUSERINFO=BID:([^\\]*),BLV.*");
        var matchName = regex.firstMatch(line);
        if (matchName != null) {
          blackName = matchName.group(1)!;
        }
      } else if (line.contains(!isError ? "GAMEWHITENAME" : "WUSERINFO=WID:")) {
        var regex = !isError
            ? RegExp(r".*GAMEWHITENAME=([^\\]*).*")
            : RegExp(r".*WUSERINFO=WID:([^\\]*),WLV.*");
        var matchName = regex.firstMatch(line);
        if (matchName != null) {
          whiteName = matchName.group(1)!;
        }
      } else if (line.startsWith("STO")) {
        //STO 0 15 2 0 15
        var step = line.split(" ");
        // var color = (int.parse(step[3]) == 1) ? "+" : "-";
        var x = int.parse(step[4]) + 1;
        var y =
            !isError ? int.parse(step[5]) + 1 : 20 - (int.parse(step[5]) + 1);
        board.put(x, y);
      }
    });
    onResponseFromOtherPlatform(
        board.toSgf(blackName: blackName, whiteName: whiteName));
  }

  _parseYH(String clipText) async {
    int id = 0;
    var matchId = RegExp(r".*chessid=(\d+).*").firstMatch(clipText);
    if (matchId != null) {
      id = int.parse(matchId.group(1)!);
    }
    int apply_uid = 0;
    var response;
    if (clipText.contains('jueyi')) {
      var apply_uid =
          int.parse(RegExp(r".*uid=(\d+).*").firstMatch(clipText)!.group(1)!);
      print('apply_uid$apply_uid');
      response = await Dio(BaseOptions(
        connectTimeout: const Duration(milliseconds: 15 * 1000),
      )).get(
          "http://h5.foxwq.com/chess/autocommentary/GetJingjieDetail?apply_uid=$apply_uid&chessid=$id");
    } else {
      response = await Dio(BaseOptions(
              connectTimeout: const Duration(milliseconds: 15 * 1000)))
          .get(
              "http://h5.foxwq.com/qqgameweiqi/chessbook_local/YHWQFetchChess?chessid=$id");
    }
    onResponseFromOtherPlatform(jsonDecode(response.data)['chess']);
  }

  _parseTX(String clipText) async {
    int id = 0;
    var matchId = RegExp(r".*chessid=(\d+).*").firstMatch(clipText);
    if (matchId != null) {
      id = int.parse(matchId.group(1)!);
    }
    var response = await Dio(BaseOptions(
            connectTimeout: const Duration(milliseconds: 15 * 1000)))
        .get(
            "https://cgi.huanle.qq.com/happyapp/cgi-bin/CommonMobileCGI/TXWQFetchChess?chessid=$id");
    onResponseFromOtherPlatform(jsonDecode(response.data)['chess']);
  }

  _parseTXSE(String clipText) async {
    int id = 0;
    var matchId = RegExp(r".*chessid=(\d+).*").firstMatch(clipText);
    if (matchId != null) {
      id = int.parse(matchId.group(1)!);
    }
    var response = await Dio(BaseOptions(
            connectTimeout: const Duration(milliseconds: 15 * 1000)))
        .get(
            "http://134.175.232.138:33631/chessbook/FetchChessBookByID?id=$id");
    onResponseFromOtherPlatform(jsonDecode(response.data)['chess']);
  }

  _parseJJ(String clipText) async {
    int id = 0;
    var matchId = RegExp(r".*sgfid=(\d+).*").firstMatch(clipText);
    if (matchId != null) {
      id = int.parse(matchId.group(1)!);
    }
    var response = await Dio(BaseOptions(
            connectTimeout: const Duration(milliseconds: 15 * 1000)))
        .get("http://getsgf.99weiqi.com/wxsgf.aspx?index=$id");
    var matchSgf = RegExp(r".*(\(;.*\)).*").firstMatch(response.data);
    if (matchSgf != null) {
      onResponseFromOtherPlatform(matchSgf.group(1)!);
    }
  }

  _parseJY(String clipText) async {
    var response = await Dio(BaseOptions(
            connectTimeout: const Duration(milliseconds: 15 * 1000)))
        .get(clipText);
    var matchInfo = RegExp(r".*var info = ({.*}).*").firstMatch(response.data);
    var matchChess =
        RegExp(r".*var arr = (\[.*\]).*").firstMatch(response.data);

    int boardSize = 19;
    //解析路数
    if (matchInfo != null) {
      var info = json.decode(matchInfo.group(1)!) as Map;
      chessType(type) {
        switch (type) {
          case 0:
            return 19;
          case 1:
            return 13;
          case 2:
            return 12;
          case 3:
            return 10;
          case 4:
            return 9;
          case 5:
            return 7;
          case 6:
            return 4;
          case 9:
            return 6;
        }
      }

      boardSize = chessType(int.parse(info['type']))!;
    }

    //解析棋谱
    if (matchChess != null) {
      var chessArr = json.decode(matchChess.group(1)!) as List;
      //按手顺排序
      chessArr.sort((a, b) {
        return int.parse(a['step_num']) - int.parse(b['step_num']);
      });
      var board = Board(boardSize);
      chessArr.forEach((element) {
        int step = int.parse(element['step']); //左上角横向从1开始
        int x = 0;
        int y = 0;
        if (step != 0) {
          x = (step - 1) % 19 + 1;
          y = (step - x) ~/ 19 + 1;
        }

        board.put(x, y);
      });

      onResponseFromOtherPlatform(board.toSgf());
    }
  }

  _parseXB(String clipText) async {
    int id = 0;
    var matchId = RegExp(r".*pid=(\d+).*").firstMatch(clipText);
    if (matchId != null) {
      id = int.parse(matchId.group(1)!);
    }
    var response = await Dio(BaseOptions(
            connectTimeout: const Duration(milliseconds: 15 * 1000)))
        .get("https://duiyi.xbkids.cn/wx/pu/getpudata.php?pid=$id");
    int boardSize = int.parse(jsonDecode(response.data)['board_size']);
    String blackName = jsonDecode(response.data)['blackname'];
    String whiteName = jsonDecode(response.data)['whitename'];
    String chess = jsonDecode(response.data)['pu'];
    chess = chess.toLowerCase();
    chess = chess.replaceAll("b[", "B[");
    chess = chess.replaceAll("w[", "W[");
    String target = "";
    for (int i = 0; i < chess.length; i++) {
      var c = chess[i];
      if (c.codeUnitAt(0) >= 'i'.codeUnitAt(0)) {
        c = String.fromCharCode(c.codeUnitAt(0) - 1);
      }
      target += c;
    }
    onResponseFromOtherPlatform(
        "(;SZ[$boardSize]PB[$blackName]PW[$whiteName];$target)");
  }

  _parseYKSE(String clipText) async {
    String param = '';
    var matchParam = RegExp(r".*p=([a-zA-Z=\d]+).*").firstMatch(clipText);
    if (matchParam != null) {
      param = matchParam.group(1)!;
    }

    var result = base64.decode(param);
    result = base64.decode(utf8.decode(result));

    var data = jsonDecode(utf8.decode(result));
    var url = "https://mo.yikeweiqi.com/yikemo/anon/ayalyse/init";
    var gameId = 0;
    var response;
    if (data.containsKey('from') && data['from'] == 'game_history') {
      gameId = data['gameId'];
      url =
          "https://mo.yikeweiqi.com/yikemo/anon/getGameDetails?gameId=$gameId";
      response = await Dio(BaseOptions(
              connectTimeout: const Duration(milliseconds: 15 * 1000)))
          .get(url);
      print('response===' + response.toString());
    } else {
      response = await Dio(BaseOptions(
              connectTimeout: const Duration(milliseconds: 15 * 1000)))
          .post(
        "https://mo.yikeweiqi.com/yikemo/anon/ayalyse/init",
        // data: jsonDecode(utf8.decode(result)),
        queryParameters: jsonDecode(utf8.decode(result)),
      );
    }

    onResponseFromOtherPlatform(gameId > 0
        ? response.data['data']['sgf']
        : response.data['aiResultList'][0]['sgfContent']);
  }

  _parseYZ(String clipText) async {
    RegExpMatch matchParam;
    if (clipText.contains('web/#/live_detail')) {
      print('clipText:$clipText');
      matchParam = RegExp(r"gameId=(\d+)&type=(\d)").firstMatch(clipText)!;
      var type = int.parse(matchParam.group(2)!);
      var gameId = int.parse(matchParam.group(1)!);
      print('info:$gameId');
      api
          .getTest(RequestModel('190105', liveDetailWebInfo(gameId, type),
              userId: 0))
          .then((value) {
        GameRoomLivingDetail _gameRoom = GameRoomLivingDetail.fromJson(value);
        String allStep = _gameRoom.f_allstep!;
        var board = Board(19);
        board.showYzSteps(allStep);
        String sgf = board.toSgf(
            blackName: _gameRoom.blackname!,
            whiteName: _gameRoom.whitename!,
            result: _gameRoom.f_result!);
        onResponseFromOtherPlatform(sgf);
      });
    } else {
      matchParam =
          RegExp(r"GoWebService/(\d)/game_(\d+).html").firstMatch(clipText)!;
      var type = int.parse(matchParam.group(1)!);
      var gameId = int.parse(matchParam.group(2)!);
      var url =
          "http://app.izis.cn:8080/GoWebService/WebGetSGFServlet?gameid=$gameId&type=$type";
      var response = await Dio(BaseOptions(
              connectTimeout: const Duration(milliseconds: 15 * 1000)))
          .get(url);
      onResponseFromOtherPlatform(response.data['sgf']);
    }
  }

  _parseXZ(String clipText) async {
    bool isLive = false;
    RegExp regExp = RegExp(r'sgf/(\d+)');
    if (clipText.contains('live')) {
      regExp = RegExp(r'/(\d+)');
      isLive = true;
    } else if (clipText.contains('report')) {
      regExp = RegExp(r'report/(\d+)');
    }
    var matchParam = regExp.firstMatch(clipText);
    if (matchParam != null) {
      var gameId = matchParam.group(1)!;
      print(gameId);
      String url = 'https://www.19x19.com/api/engine/games/0086-13548634308/' +
          gameId +
          '?id=' +
          gameId;
      if (isLive) {
        url = 'https://www.19x19.com/api/engine/golives/' + gameId;
      }
      var response = await Dio(BaseOptions(
              connectTimeout: const Duration(milliseconds: 15 * 1000)))
          .get(url);
      print(response.data);
      var data = json.decode(response.data);
      onResponseFromOtherPlatform(data['data']['sgf']);
    }
  }
}
